ggplot2(8)-坐标轴

交换x轴与y轴

1
2
library(ggplot2)
ggplot(PlantGrowth,aes(x=group,y=weight))+geom_boxplot()

mark

现在将上图中的x轴与y轴进行交换:

1
ggplot(PlantGrowth,aes(x=group,y=weight))+geom_boxplot()+coord_flip()

mark

逆转转换后的原x轴变量

中图中交换了x轴与y轴后,发现x轴的分类变量从原来的从左向右排列变成了从下往上排列,但通过scale_x_discrete()参数可以进行逆转:

1
ggplot(PlantGrowth,aes(x=group,y=weight))+geom_boxplot()+coord_flip()+scale_x_discrete(limits=rev(levels(PlantGrowth$group)))

mark

设置连续型坐标轴的值域

设置y轴的范围:

1
2
p <- ggplot(PlantGrowth,aes(x=group,y=weight))+geom_boxplot()
p

mark

将y轴的范围扩大

1
p + ylim(0,max(PlantGrowth$weight))

mark

调整y轴的范围,并且在0,5,10处加上标记

1
p + scale_y_continuous(limits=c(0,10),breaks=c(0,5,10))

mark

breaks参数中可以加入多个标记,如下所示:

mark

1
p + scale_y_continuous(limit=c(5,6.5))

mark

可以使用expand_limits()来单向扩展值域

1
p + expand_limits(y=4)

mark

反转一条连续型坐标轴

可以用scale_y_reverse()来翻转坐标轴:

1
ggplot(PlantGrowth,aes(x=group,y=weight))+geom_boxplot()+scale_y_reverse()

mark

通过指定y轴的坐标范围也可以实现以上效果,如下所示:

1
ggplot(PlantGrowth,aes(x=group,y=weight))+geom_boxplot()+ylim(6.5,3.5)

mark

翻转坐标轴并设定值域:

注意y轴数值的变化:

dmark

修改x轴上的类别的顺序

基础绘图

1
2
p <- ggplot(PlantGrowth,aes(x=group,y=weight))+geom_boxplot()
p

mark

改变x轴的顺序

可以发现,上述图的x轴顺序是ctr1,trt1,trt2,现在改变x轴的顺序:

1
p + scale_x_discrete(limits=c("trt1","ctrl","trt2"))

mark

上述代码改变x轴的顺序,将原来的顺序ctrl,trt1,trt2改变为trt1,ctrl,trt2。

反转x轴有关类型的顺序

可以用scale_x_discrete(limits=rev())来实现,原图如下:

1
2

mark

反转后的如下:

1
p + scale_x_discrete(limits=rev(levels(PlantGrowth$group)))

mark

显示其中的两项

下面的代码则只显示ctrl与trt1两组的箱线图:

1
p + scale_x_discrete(limits=c("ctrl","trt1"))

mark

设置x轴与y轴的缩放比例

先看一下原图:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
library(gcookbook)
head(marathon,8) # 先查看一下数据集,数据集marathon中包括跑步者的全程马拉松和半程马拉松
## Half Full
## 1 66.80000 141.4833
## 2 67.88333 147.2667
## 3 68.70000 147.8833
## 4 69.90000 156.7500
## 5 69.95000 147.4333
## 6 70.11667 150.0000
## 7 70.63333 147.2333
## 8 70.65000 159.0000
sp <- ggplot(marathon,aes(x=Half,y=Full)) + geom_point()
sp

mark

缩小x轴与y轴

1
sp + coord_fixed()

mark

原图中的y轴与x轴的单位长度之比为并不为1:1,加了coord_fixed()之后,y轴长度与x轴长度的单位长度之比为1:1。通过下面的案例可以更加清楚地说明。

下面的代码把x轴与y轴的单位长度设置相同,即两个刻度之间间距都是30

1
2
3
sp + coord_fixed()+
scale_y_continuous(breaks=seq(0,420,30))+
scale_x_continuous(breaks=seq(0,420,30))

mark

改变x轴与y轴的比例

通过coord_fixed(ratio=1/2)参数实现,先看一下最基本的实现方法:

1
sp + coord_fixed(ratio=1/2)

mark

上述的图形的坐标轴表示x轴是y轴的1/2,但并不直观,接下来进行更直观的设置。

把x轴的最小刻度设置为15,把y轴的最小刻度设置为30:

1
2
3
sp + coord_fixed(ratio=1/2)+
scale_y_continuous(breaks=seq(0,420,30))+
scale_x_continuous(breaks=seq(0,420,15))

mark

设置刻度线的位置

原始绘图

1
ggplot(PlantGrowth,aes(x=group,y=weight))+geom_boxplot()

mark

上述图形的坐标轴是均匀分布的,从3.5到6.0,每个间隔是0.5,现在进行更改。

更改y轴的位置

1
2
ggplot(PlantGrowth,aes(x=group,y=weight))+geom_boxplot()+
scale_y_continuous(breaks=c(4,4.25,4.5,5,6,8))

mark

可以看出来,上述的y轴坐刻度已经发生了改变,变成了4,4.25,4.5,5,6,8。其中scale_y_continuous()表示y轴的数据是连续型的。如果是离散型的则用scale_y_discrete()。

不同类型的x轴刻度

1
2
ggplot(PlantGrowth,aes(x=group,y=weight))+geom_boxplot()+
scale_x_discrete(limits=c("trt2","ctrl"),breaks="ctrl")

mark

上述的代码表示,限定x轴上只显示trt2与ctrl两组数据,但只显示ctrl这个类型的标签。

移除刻度线和标签

基本图形

1
2
p <- ggplot(PlantGrowth,aes(x=group,y=weight)) + geom_boxplot() # 先看一下最基本的图形
p

mark

移除y轴刻度

用到的代码是theme(axis.text.y=element_blank()),即通过主题的应用,把y轴的刻度改为空白,即axis.text.y=element_blank()。

1
p + theme(axis.text.y=element_blank())

mark

上面的图形把y轴的刻度标签移除了,只是把数字移除了,但刻度还存在,可以进一步把y轴的刻度线移除,如下所示,现在将x轴与y轴的上的刻度全移除,与上面的一样,即axis.ticks=element_blank()

1
p + theme(axis.ticks=element_blank(),axis.text.y=element_blank())

mark

上述图形把y轴的刻度标签(数字)与刻度线移除了。

移除刻度线,刻度标签,网格

可以通过一个参数把y轴的刻度线,刻度标签,网格线都移除,即scale_y_continuous(breaks=NULL),如下所示:

1
p + scale_y_continuous(breaks=NULL)

mark

更换主题

ggplot中的背景色默认的是灰色主题,有的时候与论文中排版不协调,可以更换为白色主题,需要的参数是theme_bw(),如下所示:

1
p + scale_y_continuous(breaks=NULL)+theme_bw()

mark

修改刻度标签的文本

基本图形

1
2
hwp <- ggplot(heightweight,aes(x=ageYear,y=heightIn))+geom_point()
hwp

mark

更改y轴的坐标标签

上述图形的y轴表示的是身高(heightIn),数字表示的是身高的数值,现在可以将数值更改为另外一种标签,即把50,56,60,66,72位置的刻度标签从数值改为”Tiny”,”Really”,”Short”,”Medium”,”Tallish”,如下所示:

1
hwp + scale_y_continuous(breaks=c(50,56,60,66,72),labels=c("Tiny","Really\nshort","Short","Medium","Tallish"))

mark

上述图形的y轴表示的内容与原始图形的一样,只是标签变了,其中"Really\nshort"表示换行。

对标签的进一步优化

下面的代码是构建一个函数,将数值转化为英尺与英寸的格式

1
2
3
4
5
6
7
8
9
10
footinch_formatter <- function(x){
foot <- floor(x/12) # floor()是取小数的整数部分
inch <- x%%12 # %%取余数
return(paste(foot,"'",inch,"\"",sep=""))
}
footinch_formatter(56:64) # 案例
## [1] "4'8\"" "4'9\"" "4'10\"" "4'11\"" "5'0\"" "5'1\"" "5'2\"" "5'3\""
## [9] "5'4\""

用labels参数将上述的函数传递给标签

1
hwp + scale_y_continuous(labels=footinch_formatter)

mark

设置刻度

从48到72,每个间隔4

1
hwp + scale_y_continuous(breaks=seq(48,72,4),labels=footinch_formatter)

mark

其余的格式设定

可以把一些时间测试转化为HH:MM:SS(时:分:秒)或者其他类似的格式。如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
timeHMS_formatter <- function(x){
h <- floor(x/60) # 小时部分
m <- floor(x%%60) # 分钟部分
s <- round(60*(x%%1)) # 舍入到最接近的秒数
lab <- sprintf("%02d:%02d:%02d",h,m,s) # 格式化数据
lab <- gsub("^00:","",lab) # 如果开头存在00:则移除
lab <- gsub("^00","",lab) # 如果形状存在0则移除
return(lab)
}
timeHMS_formatter(c(.33,50,51.25,59.32,60,60.1,130.23))
## [1] ":20" "50:00" "51:15" "59:19" "01:00:00" "01:00:06"
## [7] "02:10:14"
另外有scales包,里面有可以格式化的函数,如下所示:
library(scales)
comma(1230092123) # 在千、百万、十亿等位置向数字添加逗号
## [1] "1,230,092,123"
dollar(34.33) # 添加一个美元符号
## [1] "$34.33"
percent(c(89.34,0.034)) # 乘以100,传到到最接近的整数值,并加添一个百分号
## [1] "8,930%" "0%"
scientific(1892321122232) # 科学计数法
## [1] "1.89e+12"

修改刻度标签的外观

基本图形

1
2
3
bp <- ggplot(PlantGrowth,aes(x=group,y=weight)) +
geom_boxplot()
bp

mark

下面的命令将x轴上的三个分类变量ctrl,trt1,trt2的名称更改为Control,Treatment1,Treatment2:

1
2
3
4
5
bp <- ggplot(PlantGrowth,aes(x=group,y=weight)) +
geom_boxplot() +
scale_x_discrete(breaks=c("ctrl","trt1","trt2"),
labels=c("Control","Treatment1","Treatment2"))
bp

mark

对标签进行旋转

把x轴上的标签改为垂直,上图中的标签太长,可以将其从水平位置更改到垂直位置: angle参数用于更改标签的角度,下面是将标签更改为垂直: 其中hjust用于控制纵向对齐,vjust用于控制横向对齐。

1
bp + theme(axis.text.x = element_text(angle=90,hjust=1,vjust=0.5))

mark把把x轴上的标签旋转30度:

1
bp + theme(axis.text.x = element_text(angle=30,hjust=1,vjust=0.5))

mark

更改标签的大小,样式,字体

1
2
bp + theme(axis.text.x = element_text(family="Times",face="italic",colour="darkred",size=rel(0.9)))
#上述命令中size=rel(0.9)表示当前主题基础字体大小的0.9

mark

设置坐标轴标签

下面命令是在x轴与y轴上分别添加文本:

1
hwp + xlab("Age in years") + ylab("Height in inches")

mark

上面的命令是通过xlab()与ylab()来实现的,另外一种方法是通过labs()来实现:

1
hwp + labs(x="Age in years",y="Height in inches")

mark

坐标标签换行

1
hwp + scale_x_continuous(name="Age\n(years)") # 换行

mark4

移除坐标轴标签

原始图形

1
2
p <- ggplot(PlantGrowth,aes(x=group,y=weight)) + geom_boxplot()
p

mark

去掉坐标的标签

下面的命令是将x轴的坐标标签去掉,即去掉了”group”字样:

1
p + theme(axis.title.x=element_blank())

mark

使用xlab去除坐标标签

上面的代码是将x轴的坐标标签去掉,下方没有空余空间,另外一种方式是将坐标标签去空白表示,有空余空间,如下所示:

1
p + xlab("")

mark

解释:当用them()来设置axis.title.x=element_blank()时,x轴或y轴标度的名称是不会改变的,只是没有显示其文本,并且不会为其留出空间,而用xlab(“”)时,则是将标度的名称改变成了空白,还是会为名称留出空间。

修改坐标轴标签的外观

原始图形

1
2
3
library(gcookbook)
hwp <- ggplot(heightweight,aes(x=ageYear,y=heightIn))+geom_point()
hwp

mark

现在将上述图形中的x轴坐标标签修改为深红色(darkred),斜体(italic),大小为14(size=14):

1
hwp + theme(axis.title.x=element_text(face="italic",colour="darkred",size=14))

mark

将y轴的标签向左旋转0度(angle=0),斜体(italic)大小为14(size=14)

1
hwp + ylab("Height\n(inches)")+theme(axis.title.y=element_text(angle=0,face="italic",size=14))

mark

将y轴的标签向左旋转90度(angle=90,y轴标签的文字默认是水平的),斜体(italic),深红色(darkred),大小为14(size=14)

1
2
hwp + ylab("Height\n(inches)")+
theme(axis.title.y=element_text(angle=30,face="italic",colour="darkred",size=14))

mark

沿坐标轴添加直线:

初始图形

1
2
p <- ggplot(heightweight,aes(x=ageYear,y=heightIn)) + geom_point()
p

mark

沿坐标轴添加直线:

1
p + theme(axis.line=element_line(colour="black"))

mark

更改主题

如果绘图的主题在绘图区域的周围只有一条边,例如theme_bw()主题,则需要同时重置panel.border参数:

1
2
3
p + theme_bw()+
theme(panel.border = element_blank(),
axis.line = element_line(colour="black"))

mark

如果坐标轴上的直线太粗,则末端不会重合,如下所示:

1
2
3
p + theme_bw()+
theme(panel.border = element_blank(),
axis.line = element_line(colour="black",size=4))

mark

如果需要末端进行重合,需要添加lineed=”square”命令:

1
2
3
p + theme_bw()+
theme(panel.border = element_blank(),
axis.line = element_line(colour="black",size=4,lineend="square"))

mark

使用对数坐标轴

初始图形

1
2
3
library(MASS)
p <- ggplot(Animals,aes(x=body,y=brain,label=rownames(Animals)))+geom_text(size=3)
p

mark

修改坐标轴为对数

现在将上述图形的x轴与y轴取对数,如下所示:

1
p + scale_x_log10() + scale_y_log10()

mark

添加刻度标签:

1
p + scale_x_log10(breaks=10^(-1:5))+scale_y_log10(breaks=10^(0:3))

mark

把坐标轴的标签转化为指数记数法:

1
2
3
4
5
library(scales)
p + scale_x_log10(breaks=10^(-1:5),
labels=trans_format("log10",math_format(10^.x)))+
scale_y_log10(breaks=10^(0:3),
labels=trans_format("log10",math_format(10^.x)))

mark

下面的代码表示,先对x轴与y轴的坐标进行转换,将转换后的数据映射到坐标轴上,如下所示:

1
ggplot(Animals,aes(x=log10(body),y=log10(brain),label=rownames(Animals)))+geom_text(size=5)

mark

下面的代码是将x轴与y轴的坐标进行对数转换,对x轴进行自然对数变换,对y轴进行以2为底数的对数变换。

1
2
3
4
5
6
p + scale_x_continuous(trans = log_trans(),
breaks = trans_breaks("log",function(x) exp(x)),
labels = trans_format("log",math_format(e^.x)))+
scale_y_continuous(trans = log2_trans(),
breaks = trans_breaks("log2",function(x) 2^x),
labels= trans_format("log2",math_format(2^.x)))

mark

折线图的坐标转换

原始图形

1
ggplot(aapl,aes(x=date,y=adj_price))+geom_line()

mark

现在对y轴进行对数变换:

1
2
ggplot(aapl,aes(x=date,y=adj_price))+geom_line()+
scale_y_log10(breaks=c(2,10,50,250))

mark

为对数坐标轴添加刻度

用到的函数是annotation_logticks(),如下所示:

1
2

mark

进行一步优化刻度线

对x轴或y轴的刻度进一步设置时,可以用minor_breaks=log10(5)+ -2:5),即minor_breaks=log10(5*10^(minpow:maxpow)),这个是用来调整图形中的网格线,如下所示:

1
2
3
4
5
6
7
8
9
10
11
ggplot(Animals,aes(x=body,y=brain,label=rownames(Animals)))+
geom_text(size=3)+
annotation_logticks()+
scale_x_log10(breaks=trans_breaks("log10",function(x) 10^x),
labels=trans_format("log10",math_format(10^.x)),
minor_breaks=log10(5)+ -2:5)+
scale_y_log10(breaks=trans_breaks("log10",function(x) 10^x),
labels=trans_format("log10",math_format(10^.x)),
minor_breaks=log10(5)+ -1:3)+
coord_fixed()+
theme_bw()

mark

绘制环状图形

基础图形

1
2
3
4
5
6
7
8
9
10
11
head(wind,8)
## TimeUTC Temp WindAvg WindMax WindDir SpeedCat DirCat
## 3 0 3.54 9.52 10.39 89 10-15 90
## 4 5 3.52 9.10 9.90 92 5-10 90
## 5 10 3.53 8.73 9.51 92 5-10 90
## 6 15 3.63 8.97 9.90 94 5-10 90
## 7 20 3.71 8.51 9.41 97 5-10 90
## 8 25 3.73 8.43 9.02 95 5-10 90
## 9 30 3.56 8.12 8.92 98 5-10 105
## 10 35 3.63 8.47 9.11 101 5-10 105

先以直方图的形式绘制出来,x轴是DirCat,按SpeedCat进行填充,条形图的组距是15,开始位置是-7.5,x轴的位置范围是0到360。

1
2
3
ggplot(wind,aes(x=DirCat,fill=SpeedCat))+
geom_histogram(binwidth=15,origin=-7.5)+
scale_y_continuous(breaks=seq(0,60,10))

mark

极坐标只是将上述的条形图卷曲成了圆形,书中的坐标轴标记是0到60,最小单位是10,但按照书中的代码并不能绘图出来,因此,下面的代码中加入了scale_y_continuous(breaks=seq(0,60,10))。如下所示:

1
2
3
4
ggplot(wind,aes(x=DirCat,fill=SpeedCat))+
geom_histogram(binwidth=15,origin=-7.5)+
scale_y_continuous(breaks=seq(0,60,10))+
coord_polar()

mark

极坐标的进一步优化

改变直方图的轮廓为黑色(colour=”black”),尺寸为0.25(size=0.25),改变图例的顺序(fill=guide_legend(reverse=TRUE)),优化颜色(scale_fill_brewer()),如下所示:

1
2
3
4
5
ggplot(wind,aes(x=DirCat,fill=SpeedCat))+
geom_histogram(binwidth=15,origin=-7.5,colour="black",size=0.25)+
guides(fill=guide_legend(reverse=TRUE))+
coord_polar()+
scale_x_continuous(limits=c(0,360),breaks=seq(0,360,by=45),minor_breaks=seq(0,360,by=15))+scale_fill_brewer()

mark

参考资料

  1. 常肖楠, 邓一硕, 魏太云. R数据可视化手册[M]. 人民邮电出版社, 2014.